package com.dd.cloud.user.service.common.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dd.cloud.common.config.map.MapUtils;
import com.dd.cloud.common.config.weather.WeatherUtils;
import com.dd.cloud.common.constants.HealthConstants;
import com.dd.cloud.common.constants.RedisKeyConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.utils.HttpRequestUtils;
import com.dd.cloud.common.utils.IPUtil;
import com.dd.cloud.common.utils.RandomImageCodeUtil;
import com.dd.cloud.common.vo.LngLatInfoVo;
import com.dd.cloud.common.vo.WeatherInfoVo;
import com.dd.cloud.user.service.common.ICommonService;
import com.dd.cloud.user.vo.ChatGptParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Lx
 * @version 1.0
 */
@Slf4j
@Service
public class CommonServiceImpl implements ICommonService {
    private final String IMAGE_CODE_KEY_PREFIX = "image-code-";
    private final String IP_ADDR_KEY_PREFIX = "ip-addr-";
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MapUtils mapUtils;
    @Autowired
    private WeatherUtils weatherUtils;
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 生成图形验证码
     *
     * @param response
     * @param key
     */
    @Override
    public void createImageCode(HttpServletResponse response, String key) {
        try {
            //设置相应类型,告诉浏览器输出的内容为图片
            response.setContentType("image/jpeg");
            //设置响应头信息，告诉浏览器不要缓存此内容
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            RandomImageCodeUtil randomValidateCode = new RandomImageCodeUtil();
            //输出验证码图片方法
            randomValidateCode.getRandCode(redisTemplate, IMAGE_CODE_KEY_PREFIX + key, response);
        } catch (Exception e) {
            log.error("获取验证码失败>>>>   ", e);
        }
    }

    /**
     * 验证图形验证码
     *
     * @param key
     * @param code
     * @return
     */
    @Override
    public boolean verifyImageCode(String key, String code) {
        return RandomImageCodeUtil.checkImgRandom(code, redisTemplate, IMAGE_CODE_KEY_PREFIX + key);
    }

    /**
     * 根据地址获取经纬度
     *
     * @param addr
     * @return
     */
    @Override
    public LngLatInfoVo geocodingUrl(String addr) {
        return mapUtils.geocodingUrl(addr);
    }

    public static void main(String[] args) {
        ChatGptParams chatGptParams = new ChatGptParams();
        chatGptParams.setNetwork(true);
        chatGptParams.setPrompt("咳嗽口语化表达");
        chatGptParams.setStream(false);
        chatGptParams.setUserId("#/chat/1698301361790");
        chatGptParams.setWithoutContext(true);
        chatGptParams.setSystem("");
        String url = "https://api.binjie.fun/api/generateStream?refer__1360=n40x9DcDnDyiY7KKGNDQTiQj3iIq%2BqE4Y5Ktx";
        HashMap<String, String> map = new HashMap<>();
        map.put("Referer", "https://chat18.aichatos.xyz/");
        map.put("Accept", "application/json, text/plain, */*");
        map.put("Origin", "https://chat18.aichatos.xyz");
        map.put("Content-Type", "application/json");
        String s = JSONObject.toJSON(chatGptParams).toString();
        System.out.println("请求:" + s);
        try {
            String post = HttpRequestUtils.post(url, s, map);
            System.out.println("返回:" + post);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //String res = restTemplate.postForObject(url, entity, String.class);
    }

    /**
     * @param : account 账号
     * @return void
     * @description 验证密码错误次数
     * @author czg
     * @date 2023/12/5 11:23
     */
    @Override
    public void checkLoginPwdError(HttpServletRequest request, String account) {
        String client = request.getHeader("client");
        String key = client + RedisKeyConstants.PWD_ERROR + account;
        if (!redisTemplate.hasKey(key)) {
            return;
        }
        Integer errorNum;
        try {
            errorNum = Integer.valueOf(redisTemplate.opsForValue().get(key));
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        Integer num = HealthConstants.getClientLoginErrorNum(client);
        if (errorNum >= num) {
            //密码错误已达阈值
            throw new ZekeException("密码错误已超过" + num + "次, 请" + HealthConstants.CLIENT_LOGIN_ERROR_TIME + "分钟后重试");
        }
    }

    /**
     * 查询天气信息
     *
     * @param province
     * @param city
     * @param ip
     * @return
     */
    @Override
    public WeatherInfoVo getWeatherInfo(String province, String city, String ip, HttpServletRequest request) {
        if (StringUtils.isBlank(city) && StringUtils.isBlank(ip)) {
            ip = IPUtil.getIpAddress(request);
        }
        if (StringUtils.isBlank(city)) {
            String value = redisTemplate.opsForValue().get(IP_ADDR_KEY_PREFIX + ip);
            if (StringUtils.isNotBlank(value)) {
                IPUtil.IpAddr ipAddr = JSON.parseObject(value, IPUtil.IpAddr.class);
                province = ipAddr.getInfo1();
                city = ipAddr.getInfo3();
            } else {
                IPUtil.IpAddr ipAddr = null;
                try {
                    ipAddr = IPUtil.getIpAddr(ip);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (ipAddr != null) {
                    ipAddr.setInfo1(ipAddr.getInfo1().replace("省", ""));
                    ipAddr.setInfo2(ipAddr.getInfo2().replace("市", ""));
                    province = ipAddr.getInfo1();
                    city = ipAddr.getInfo2();
                    redisTemplate.opsForValue().set(IP_ADDR_KEY_PREFIX + ip, JSON.toJSONString(ipAddr), 4L, TimeUnit.HOURS);
                }
            }
        }
        log.info("province:{},city:{},ip:{}", province, city, ip);
        return weatherUtils.getWeatherInfo(province, city, ip);
    }

    /**
     * @param request:
     * @param account:
     * @return void
     * @description 密码错误增加次数
     * @author czg
     * @date 2023/12/5 14:42
     */
    @Override
    public void loginPwdError(HttpServletRequest request, String account) {
        String client = request.getHeader("client");
        String key = client + RedisKeyConstants.PWD_ERROR + account;
        redisTemplate.opsForValue().increment(key, 1).intValue();
        redisTemplate.expire(key, HealthConstants.CLIENT_LOGIN_ERROR_TIME, TimeUnit.MINUTES);
    }

    /**
     * @param :
     * @return void
     * @description 通过chatgpt获取症状的口语化描述
     * @author czg
     * @date 2023/12/18 10:14
     */
    @Override
    public void getSymptomInfoFromGpt(HttpServletRequest request) {
        ChatGptParams chatGptParams = new ChatGptParams();
        chatGptParams.setNetwork(true);
        chatGptParams.setPrompt("你是医学科普专家，请用第一人称口语化描述“咽干”的症状，500字");
        chatGptParams.setStream(false);
        chatGptParams.setUserId("#/chat/1698301361767");
        chatGptParams.setWithoutContext(true);
        chatGptParams.setSystem("");
        String url = "https://api.binjie.fun/api/generateStream?refer__1360=n40x9DcDnDyiY7KKGNDQTiQj3iIq%2BqE4Y5536";
        HttpHeaders head = new HttpHeaders();
//        head.add("Origin", "https://chat18.aichatos.xyz");
        head.add("Referer", "https://chat18.aichatos.xyz/");
//        head.add("Accept", "application/json, text/plain, */*");
        List<MediaType> accept = new ArrayList<>();
        accept.add(MediaType.APPLICATION_JSON);
        accept.add(MediaType.TEXT_PLAIN);
        accept.add(MediaType.ALL);
        head.setAccept(accept);
        head.setOrigin("https://chat18.aichatos.xyz");
        head.setContentType(MediaType.APPLICATION_JSON);
        head.add("User-Agent", request.getHeader("User-Agent"));

//        HttpEntity<String> entity = new HttpEntity<>(JsonUtils.objectToStr(chatGptParams), head);
//        log.info("gpt请求参数:{}", JsonUtils.objectToStr(chatGptParams));
//        String res = restTemplate.postForObject(url, entity, String.class);
//        log.info("gpt返回数据:{}", res);
        HashMap<String, String> map = new HashMap<>();
        map.put("Referer", "https://chat18.aichatos.xyz/");
        map.put("Accept", "application/json, text/plain, */*");
        map.put("Origin", "https://chat18.aichatos.xyz");
        map.put("Content-Type", "application/json");
        map.put("User-Agent", request.getHeader("User-Agent"));

        String s = JSONObject.toJSON(chatGptParams).toString();
        log.info("gpt请求数据:" + s);

        try {
            String post = HttpRequestUtils.post(url, s, map);
            log.info("gpt返回数据:" + post);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
